#include "Windows7PrinterDriverInstaller.h"
#include "Windows7VirtualPrinterCreator.h"
#include <string>
#include "Windows7PrinterDriverInstaller.h"
#include "Windows7VirtualPrinterCreator.h"  
#include <fstream>
#define CONFIG_FILE_PATH "C:\\PrintToCups\\printInspect.conf"
#define LINE_LENGTH 1024 
#define ERROR_LOG_FILE_PATH (LPWSTR)L"C:\\PrintToCups\\AddMutilVirtualPrinterError.log"
#define INFO_LOG_FILE_PATH (LPWSTR)L"C:\\PrintToCups\\AddMutilVirtualPrinterInfo.log"
#define LOG_BUFFER_SIZE 1024
void AppendErrorLogToFile(const char* log)
{
    char log_buffer[LOG_BUFFER_SIZE];
    HANDLE hFile = NULL;
    time_t currentTime;
    struct tm* timeInfo;
    DWORD write_size = 0;

    memset(log_buffer, 0, sizeof(log_buffer));

    hFile = CreateFileW(ERROR_LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        do {
            hFile = CreateFileW(ERROR_LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE) {
                break;
            }

            CloseHandle(hFile);
            hFile = CreateFileW(ERROR_LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        } while (false);
    }

    if (hFile == INVALID_HANDLE_VALUE) {
        return;
    }

    SetFilePointer(hFile, (LONG)NULL, (PLONG)NULL, FILE_END);

    memset(log_buffer, 0, sizeof(log_buffer));

    currentTime = time(NULL);
    timeInfo = localtime(&currentTime);
    strftime(log_buffer, sizeof(log_buffer), "%Y-%m-%d %H:%M:%S", timeInfo);

    strncat(log_buffer, "Error <<========write log========>> :: ", strlen(" <<========write log========>> :: "));
    strncat(log_buffer, log, strlen(log));
    strncat(log_buffer, "\r\n", strlen("\r\n"));

    if (!WriteFile(hFile, log_buffer, strlen(log_buffer), &write_size, NULL)) {
        MessageBoxA(0, "AddPrinter Log Write Failed","INFO",MB_OK);
    }

    CloseHandle(hFile);
    hFile = INVALID_HANDLE_VALUE;
}

void AppendInfoLogToFile(const char* log)
{
    char log_buffer[LOG_BUFFER_SIZE];
    HANDLE hFile = NULL;
    time_t currentTime;
    struct tm* timeInfo;
    DWORD write_size = 0;

    memset(log_buffer, 0, sizeof(log_buffer));

    hFile = CreateFileW(INFO_LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        do {
            hFile = CreateFileW(INFO_LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE) {
                break;
            }

            CloseHandle(hFile);
            hFile = CreateFileW(INFO_LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        } while (false);
    }

    if (hFile == INVALID_HANDLE_VALUE) {
        return;
    }

    SetFilePointer(hFile, (LONG)NULL, (PLONG)NULL, FILE_END);

    memset(log_buffer, 0, sizeof(log_buffer));

    currentTime = time(NULL);
    timeInfo = localtime(&currentTime);
    strftime(log_buffer, sizeof(log_buffer), "%Y-%m-%d %H:%M:%S", timeInfo);

    strncat(log_buffer, "Info <<========write log========>> :: ", strlen(" <<========write log========>> :: "));
    strncat(log_buffer, log, strlen(log));
    strncat(log_buffer, "\r\n", strlen("\r\n"));

    if (!WriteFile(hFile, log_buffer, strlen(log_buffer), &write_size, NULL)) {
        MessageBoxA(0, "AddPrinter Log Write Failed", "INFO", MB_OK);
    }

    CloseHandle(hFile);
    hFile = INVALID_HANDLE_VALUE;
}

int main() {
    char szFileLineStrData[LINE_LENGTH];
    memset(szFileLineStrData, 0, sizeof(szFileLineStrData));
    WCHAR* wszPrinterName = NULL;
    std::ifstream inputFile(CONFIG_FILE_PATH);
    char szLogBuff[LOG_BUFFER_SIZE];

    if (inputFile.is_open()) {
        while (inputFile.getline(szFileLineStrData, LINE_LENGTH))
        {
            int dwEnumIndex = 0;
            while (szFileLineStrData[dwEnumIndex] != '=') {
                dwEnumIndex++;
                if (dwEnumIndex >= LINE_LENGTH) {
                    break;
                }
            }

            if (dwEnumIndex >= LINE_LENGTH) {
                continue;
            }
            else {
                szFileLineStrData[dwEnumIndex] = '\0';
            }

            int nLen = MultiByteToWideChar(CP_ACP, 0, szFileLineStrData, -1, NULL, 0);
            if (nLen <= 0) {
                memset(szLogBuff, 0, sizeof(szLogBuff));
                sprintf_s(szLogBuff, sizeof(szLogBuff), "main(): Add Printer --MultiByteToWideChar Error");
                AppendErrorLogToFile(szLogBuff);
                continue;
            }

            wszPrinterName = new WCHAR[nLen];
            if (wszPrinterName == NULL) {
                memset(szLogBuff, 0, sizeof(szLogBuff));
                sprintf_s(szLogBuff, sizeof(szLogBuff), "main(): Malloc Memory Error");
                AppendErrorLogToFile(szLogBuff);
                continue;
            }

            MultiByteToWideChar(CP_ACP, 0, szFileLineStrData, -1, wszPrinterName, nLen);

            Windows7PrinterDriverInstaller* w7DriverInstall = new Windows7PrinterDriverInstaller();
            if (w7DriverInstall == NULL) {
                delete[] wszPrinterName;
                wszPrinterName = NULL;

                memset(szLogBuff, 0, sizeof(szLogBuff));
                sprintf_s(szLogBuff, sizeof(szLogBuff), "main(): Malloc Memory Error");
                AppendErrorLogToFile(szLogBuff);
                continue;
            }

            if (!w7DriverInstall->VirtualPrinterDriverInstall(wszPrinterName)) {
                memset(szLogBuff, 0, sizeof(szLogBuff));
                sprintf_s(szLogBuff, sizeof(szLogBuff), "main(): Add Printer Driver %s Failed", szFileLineStrData);
                AppendErrorLogToFile(szLogBuff);
                delete w7DriverInstall;
                w7DriverInstall = NULL;
                delete[] wszPrinterName;
                wszPrinterName = NULL;
                continue;
            }

            delete w7DriverInstall;
            w7DriverInstall = NULL;

            Windows7VirtualPrinterCreator* w7PrinterCreator = new Windows7VirtualPrinterCreator();
            if (w7PrinterCreator == NULL) {
                delete[] wszPrinterName;
                wszPrinterName = NULL;
                memset(szLogBuff, 0, sizeof(szLogBuff));
                sprintf_s(szLogBuff, sizeof(szLogBuff), "main():Malloc Memory Error");
                AppendErrorLogToFile(szLogBuff);
                continue;
            }

            if (!w7PrinterCreator->AddNewCommonVirtualPrinter(wszPrinterName, wszPrinterName)) {
                memset(szLogBuff, 0, sizeof(szLogBuff));
                sprintf_s(szLogBuff, sizeof(szLogBuff), "main():Add Printer %s Failed", szFileLineStrData);
                AppendErrorLogToFile(szLogBuff);
            }

            delete w7PrinterCreator;
            w7PrinterCreator = NULL;

            delete[] wszPrinterName;
            wszPrinterName = NULL;

            memset(szLogBuff, 0, sizeof(szLogBuff));
            sprintf_s(szLogBuff, sizeof(szLogBuff), "main():Add Printer %s Success", szFileLineStrData);
            AppendInfoLogToFile(szLogBuff);
        }

        inputFile.close();
    }
    else {
        memset(szLogBuff, 0, sizeof(szLogBuff));
        sprintf_s(szLogBuff, sizeof(szLogBuff), "main():Open Config File Error %s Failed", CONFIG_FILE_PATH);
        AppendErrorLogToFile(szLogBuff);
    }

	return 0;
}